/*
*Copyright (c) Nikhil Jain.
*Project ICARUS, communications and 
*artificial intelligence.
*/



package javadrone.util;

//~--- non-JDK imports --------------------------------------------------------

import com.engidea.comm.*;
import com.engidea.win32jcom.WinjcomIdentifier;

//~--- JDK imports ------------------------------------------------------------

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import java.util.Iterator;
import java.util.List;

/*
WinJcom is a native interface to serial ports in java.
Copyright 2007 by Damiano Bolla, Jcomm@engidea.com

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License
 */

/**
 * Simple class that can list system ports and allow IO
 */
public class PortTester {
    private CommPortIdentifier portIdentifier;
    private SerialPort         serport;

    public static void main(String[] args) {
        PortTester portTester = new PortTester();

        portTester.StartTest();
    }

    private void report(String msg) {
        System.out.println(msg);
    }

    private void StartTest() {
        portIdentifier = new WinjcomIdentifier(0);
        listComPorts();
        selectComport();
        new Thread(new PortReader()).start();
        typeSendBytes();
    }

    private void typeSendBytes() {
        try {
            BufferedReader in   = new BufferedReader(new InputStreamReader(System.in));
            String         aStr = "";

            while (aStr != null) {
                System.out.print("type something to send> ");
                aStr = in.readLine();
                aStr += "\r\n";

                // WARNING: be careful, you shoulod select the encoding !
                // This will timeout if you have FLOW CONTROL and theline is stuck !
                byte[] buf = aStr.getBytes();

                serport.write(buf, 0, buf.length);
            }
        } catch (Exception exc) {
            exc.printStackTrace();
        }
    }

    private void listComPorts() {
        List portlist = portIdentifier.getCommPortList();

        for (Iterator iter = portlist.iterator(); iter.hasNext(); ) {
            CommPort identifier = (CommPort) iter.next();

            System.out.println("Available port name=" + identifier.getName());
        }
    }

    private SerialPort openPort(String portName) {
        try {
            CommPort aPort = portIdentifier.getCommPort(portName);

            aPort.open();

            return (SerialPort) aPort;
        } catch (Exception exc) {
            report("exc=" + exc);
            exc.printStackTrace();
        }

        return null;
    }

    private void selectComport() {
        try {
            BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

            System.out.print("type port name> ");

            String portname = in.readLine();

            serport = openPort(portname);
            serport.setSerialPortParams(9600, 8, SerialPort.STOPBITS_2, SerialPort.PARITY_NONE);
            serport.enableReceiveTimeout(20000);
            serport.setEventListener(new EventListener());
            serport.notifyOnDSR(true);
            serport.notifyOnCarrierDetect(true);
            serport.notifyOnCTS(true);

//          serport.notifyOnOutputEmpty(true);
        } catch (IOException exc) {
            report("Exc=" + exc);
            exc.printStackTrace();
        }
    }

    private final class EventListener implements SerialPortEventListener {
        public void serialEvent(SerialPortEvent ev) {
            System.out.println("Got event=" + ev);
        }
    }


    private final class PortReader implements Runnable {
        public void run() {
            try {

                // This will timeout if nothing is received in the specified time.
                byte[] buff = new byte[1];

                while (serport.read(buff, 0, buff.length) > 0) {

                    // NOTE: you should be checking the encoding !
                    System.out.print(new String(buff));
                }
            } catch (Exception exc) {
                exc.printStackTrace();
            }
        }
    }
}


//~ Formatted by Jindent --- http://www.jindent.com
